package main
import (
	"fmt"
    "studygolang/16computer"
)

// 创建命名的结构体
type Employee struct {
    firstName, lastName string
    age, salary int
}

// 匿名字段
type Person struct {
    string
    int
}


//  16. 结构体
func main(){
    emp1 := Employee{
        firstName: "yang",
        lastName: "hao",
        age: 18,
        salary: 500,
    }
    emp2 := Employee{"yang1", "hao1", 19, 800}
    fmt.Println("emp1 = ", emp1)
    fmt.Println("emp2 = ", emp2)

    // 创建匿名结构体
    emp3 := struct {
        firstName, lastName string
        age, salary int
    }{
        firstName: "Yang",
        lastName: "Hao",
        age: 31,
        salary: 500000,
    }
    fmt.Println("\n匿名 emp3 = ", emp3)

    // 结构体的零值（Zero Value）
    var emp4 Employee
    fmt.Println("\n 结构体的零值 emp4 = ", emp4)
    emp5 := Employee {
        firstName: "yang",
        lastName: "Hao",
    }
    fmt.Println("\n 结构体的零值 emp5 = ", emp5)

    // 访问结构体的字段
    emp6 := Employee{"yang", "hao", 18, 80000}
    fmt.Println("\nFirst Name:", emp6.firstName)
    fmt.Println("Last Name:", emp6.lastName)
    fmt.Println("Age:", emp6.age)
    fmt.Printf("Salary: $%d\n", emp6.salary)

    // 结构体的指针
    emp8 := &Employee{"yang", "hao", 18, 80000}
    fmt.Println("\nFirst Name:",(*emp8).firstName)
    fmt.Println("Age:", emp8.age) //可以不用*

    // 匿名字段
    per1 := Person{"yangaho", 20}
    fmt.Println("\n 匿名字段 per1 = ", per1)

    // 虽然匿名字段没有名称，但其实匿名字段的名称就默认为它的类型
    var per2 Person
    per2.string ="yanghao"
    per2.int = 50
    fmt.Println("\n 匿名字段-类型 per2 = ", per2)

    // 嵌套结构体（Nested Structs）
    var aper1 Person1
    aper1.name = "yanghao"
    aper1.age = 50
    // aper1.address = Address {
    //     city: "广州",
    //     state: "state1",
    // }
    aper1.address.city = "广州"
    aper1.address.state = "state1"
    fmt.Println("\nName:", aper1.name)
    fmt.Println("Age:",aper1.age)
    fmt.Println("City:",aper1.address.city)
    fmt.Println("State:",aper1.address.state)

    // 提升字段（Promoted Fields）
    var aper2 Person2
    aper2.name = "yanghao"
    aper2.age = 50
    // aper2.Address = Address{
    //     city:  "Chicago",
    //     state: "Illinois",
    // }
    aper2.city = "广州"
    aper2.state = "state1"
    fmt.Println("\n aper2 -----Name:", aper2.name)
    fmt.Println("Age:", aper2.age)
    fmt.Println("City:", aper2.city) //city is promoted field
    fmt.Println("State:", aper2.state) //state is promoted field


    // 导出结构体和字段
    var spec1 computer.Spec
    spec1.Maker = "apple"
    spec1.Price = 5000
    // spec.model = "Mac Mini"//报错
    fmt.Println("\n spec1:",spec1)


    // 结构体相等性（Structs Equality）
    name1 := name{"Steve", "Jobs"}
    name2 := name{"Steve", "Jobs"}
    if name1 == name2 {
        fmt.Println("name1 and name2 are equal")
    } else {
        fmt.Println("name1 and name2 are not equal")
    }

    name3 := name{firstName:"Steve", lastName:"Jobs"}
    name4 := name{}
    name4.firstName = "Steve"
    // name4.lastName = "Jobs" //开启就是一样的
    if name3 == name4 {
        fmt.Println("name3 and name4 are equal")
    } else {
        fmt.Println("name3 and name4 are not equal")
    }

}

// 嵌套结构体（Nested Structs）
type Address struct {
    city, state string
}
type Person1 struct {
    name string
    age int
    address Address
}
// 提升字段（Promoted Fields）
type Person2 struct {
    name string
    age int
    Address
}
// 结构体相等性（Structs Equality）
type name struct {  
    firstName string
    lastName string
}
